package com.sh.rbac.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sh.rbac.core.common.constant.CommonConstants;
import com.sh.rbac.core.common.enums.UserTypeEnum;
import com.sh.rbac.core.common.exception.CustomException;
import com.sh.rbac.core.common.result.ResultCodeEnum;
import com.sh.rbac.core.mybatis.annotation.DataPermission;
import com.sh.rbac.core.security.util.SecurityHolderUtils;
import com.sh.rbac.domain.converter.UserConverter;
import com.sh.rbac.domain.dto.user.*;
import com.sh.rbac.domain.entity.Role;
import com.sh.rbac.domain.entity.User;
import com.sh.rbac.domain.entity.UserRole;
import com.sh.rbac.domain.vo.user.UserVO;
import com.sh.rbac.mapper.RoleMapper;
import com.sh.rbac.mapper.UserMapper;
import com.sh.rbac.mapper.UserRoleMapper;
import com.sh.rbac.service.ParamService;
import com.sh.rbac.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author lucky
 * @description 针对表【sys_user(用户表)】的数据库操作Service实现
 * @createDate 2024-04-04 21:47:19
 */

@Transactional
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private ParamService paramService;


    @DataPermission(userColumn = "id")
    @Override
    public void checkDataScope(List<Long> ids) {
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.in(User::getId, ids);

        long count = count(lqw);
        if (count != ids.size()) {
            throw new CustomException(ResultCodeEnum.NOT_DATA_SCOPE);
        }
    }

    @Override
    public UserVO getById(Long id) {
        User user = baseMapper.selectById(id);
        List<Role> roles = roleMapper.getRolesByUserId(UserTypeEnum.isAdmin(user.getUsertype()) ? null : user.getId());
        UserVO userVO = UserConverter.INSTANCE.toVO(user);
        userVO.setRoleIds(roles.stream().map(Role::getId).toList());
        return userVO;
    }

    @DataPermission(userColumn = "id")
    @Override
    public List<UserVO> getList() {
        return UserConverter.INSTANCE.toVOList(super.list());
    }

    @DataPermission(userColumn = "id")
    @Override
    public Page<UserVO> getPage(Long current, Long limit, UserQueryDTO userQueryDTO) {
        // 创建 page 对象，传递当前页, 每页记录数
        Page<User> page = new Page<>(current, limit);

        // 条件参数
        Long deptId = userQueryDTO.getDeptId();
        String username = userQueryDTO.getUsername();
        String email = userQueryDTO.getEmail();
        String phone = userQueryDTO.getPhone();
        Integer sex = userQueryDTO.getSex();
        Integer status = userQueryDTO.getStatus();
        Long userId = SecurityHolderUtils.getUserId();

        // 构建条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(deptId != null && deptId != 0, User::getDeptId, deptId);
        queryWrapper.like(StrUtil.isNotBlank(username), User::getUsername, username);
        queryWrapper.like(StrUtil.isNotBlank(email), User::getEmail, email);
        queryWrapper.like(StrUtil.isNotBlank(phone), User::getPhone, phone);
        queryWrapper.eq(sex != null, User::getSex, sex);
        queryWrapper.eq(status != null, User::getStatus, status);
        queryWrapper.notIn(userId != null, User::getId, userId);

        // 根据修改时间倒序
        queryWrapper.orderByDesc(User::getUpdateTime);

        // 查询
        Page<User> userPage = baseMapper.selectPage(page, queryWrapper);

        // 封装
        Page<UserVO> p = Page.of(current, limit, userPage.getTotal());
        p.setRecords(UserConverter.INSTANCE.toVOList(userPage.getRecords()));

        return p;
    }


    @Override
    public Boolean save(UserSaveDTO userSaveDTO) {
        // 判断用户名是否已存在
        this.checkUsername(userSaveDTO.getUsername());

        // 密码加密
        userSaveDTO.setPassword(passwordEncoder.encode(userSaveDTO.getPassword()));

        // 保存用户
        User user = UserConverter.INSTANCE.toEntity(userSaveDTO);
        boolean b = super.save(user);

        // 保存用户角色
        userSaveDTO.getRoleIds().forEach(roleId -> userRoleMapper.insert(new UserRole(null, user.getId(), roleId)));

        // 返回结果
        return b;
    }

    @Override
    public Boolean updateById(UserUpdateDTO userUpdateDTO) {
        // 修改用户
        User user = UserConverter.INSTANCE.toEntity(userUpdateDTO);
        boolean b = super.updateById(user);

        // 删除用户绑定的角色
        userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, user.getId()));

        // 保存用户角色
        userUpdateDTO.getRoleIds().forEach(roleId -> userRoleMapper.insert(new UserRole(null, user.getId(), roleId)));

        // 返回结果
        return b;
    }

    @Override
    public Boolean updatePassword(UserUpdatePwdDTO userUpdatePwdDTO) {
        // 获取用户信息
        User user = SecurityHolderUtils.getLoginUser();

        // 判断密码是否相同
        if (passwordEncoder.matches(userUpdatePwdDTO.getOldPassword(), user.getPassword())) {
            // 修改密码
            user.setPassword(passwordEncoder.encode(userUpdatePwdDTO.getNewPassword()));

            return super.updateById(user);
        } else {
            throw new CustomException(ResultCodeEnum.OLD_PASSWORD_ERROR);
        }
    }

    @Override
    public Boolean updateProfile(UserProfileDTO userProfileDTO) {
        // 获取当前登录用户
        userProfileDTO.setId(SecurityHolderUtils.getUserId());

        // 修改用户个人信息
        User user = UserConverter.INSTANCE.toEntity(userProfileDTO);
        return super.updateById(user);
    }

    @Override
    public Boolean resetPassword(Long id) {
        //  获取系统用户默认密码
        String defaultPassword = paramService.getParamValueByCode(CommonConstants.DEFAULT_PASSWORD_CODE);

        if (defaultPassword == null) {
            defaultPassword = "123456";
        }

        // 修改用户密码
        User user = new User();
        user.setId(id);
        user.setPassword(passwordEncoder.encode(defaultPassword));

        return super.updateById(user);
    }

    @Override
    public Boolean assignRole(AssignRoleDTO assignRoleDTO) {
        // 删除用户角色
        userRoleMapper.delete(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, assignRoleDTO.getUserId()));

        // 判断用户分配的角色是否为空
        if (ObjectUtil.isNotEmpty(assignRoleDTO.getRoleIds())) {
            userRoleMapper.insertBatch(assignRoleDTO);
        }

        return true;
    }

    @Override
    public Boolean updateStatus(Long id, Integer status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);

        return super.updateById(user);
    }


    /**
     * 检查用户名是否存在
     *
     * @param username 用户名
     */
    private void checkUsername(String username) {
        User user = getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));

        if (ObjectUtil.isNotEmpty(user)) {
            throw new CustomException(ResultCodeEnum.USERNAME_EXIST);
        }
    }
}




